package com.matrix.framework.sysconfig.token.controller;

import com.matrix.framework.sysconfig.token.data.SysConfigPo;
import com.matrix.framework.sysconfig.token.service.SysConfigService;
import com.matrix.framework.core.annotation.validation.LogCollector;
import com.matrix.framework.core.common.result.Result;
import com.matrix.framework.core.i18n.I18n;
import com.matrix.framework.core.i18n.MessageConstants;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;

/**
 * 系统配置控制器
 * 
 * Copyright © 海平面工作室 版权所有
 *
 * @Author: Leo
 * @Create: 2025/06/23 23:25
 * @Since 1.2
 */
@RestController
@RequestMapping("/sysconfig")
public class SysConfigController {

    private final SysConfigService sysConfigService;

    public SysConfigController(SysConfigService sysConfigService) {
        this.sysConfigService = sysConfigService;
    }

    /**
     * 分页查询系统配置列表
     */
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sysconfig:list')")
    public Mono<Result<Map<String, Object>>> list(
            @RequestParam(value = "page", defaultValue = "1") int page,
            @RequestParam(value = "pageSize", defaultValue = "10") int size,
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "sort", required = false) String sort) {

        PageRequest pageable = PageRequest.of(page - 1, size);

        return sysConfigService.findAll(pageable, search, sort)
                .map(Result::ok)
                .onErrorResume(e -> Mono.just(Result.<Map<String, Object>>fail().message(e.getMessage())));
    }

    /**
     * 根据配置键查询配置详情
     */
    @GetMapping("/{key}")
    @PreAuthorize("hasAuthority('sysconfig:detail')")
    public Mono<Result<SysConfigPo>> detail(@PathVariable String key) {
        return sysConfigService.findByKey(key)
                .map(Result::ok)
                .switchIfEmpty(Mono.just(Result.<SysConfigPo>fail().message(I18n.getMessage(MessageConstants.DATA_NOT_FOUND))))
                .onErrorResume(e -> Mono.just(Result.<SysConfigPo>fail().message(e.getMessage())));
    }

    /**
     * 新增配置
     */
    @PostMapping
    @PreAuthorize("hasAuthority('sysconfig:add')")
    @LogCollector
    public Mono<Result<SysConfigPo>> add(@RequestBody SysConfigPo sysConfig) {
        return sysConfigService.add(sysConfig)
                .map(saved -> Result.ok(saved).message(I18n.getMessage(MessageConstants.SAVE_SUCCESS)))
                .onErrorResume(e -> Mono.just(Result.<SysConfigPo>fail().message(e.getMessage())));
    }

    /**
     * 修改配置
     */
    @PutMapping("/{key}")
    @PreAuthorize("hasAuthority('sysconfig:edit')")
    @LogCollector
    public Mono<Result<SysConfigPo>> edit(@PathVariable String key, @RequestBody SysConfigPo sysConfig) {
        return sysConfigService.update(key, sysConfig)
                .map(saved -> Result.ok(saved).message(I18n.getMessage(MessageConstants.UPDATE_SUCCESS)))
                .onErrorResume(e -> Mono.just(Result.<SysConfigPo>fail().message(e.getMessage())));
    }

    /**
     * 保存或更新配置
     */
    @PostMapping("/save")
    //@PreAuthorize("hasAuthority('sysconfig:edit')")
    @LogCollector
    public Mono<Result<SysConfigPo>> save(@RequestBody SysConfigPo sysConfig) {
        return sysConfigService.save(sysConfig)
                .map(saved -> Result.ok(saved).message(I18n.getMessage(MessageConstants.SAVE_SUCCESS)))
                .onErrorResume(e -> Mono.just(Result.<SysConfigPo>fail().message(e.getMessage())));
    }

    /**
     * 根据配置键删除配置
     */
    @DeleteMapping("/{key}")
    @PreAuthorize("hasAuthority('sysconfig:delete')")
    @LogCollector
    public Mono<Result<Object>> delete(@PathVariable String key) {
        return sysConfigService.deleteByKey(key)
                .then(Mono.just(Result.ok().message(I18n.getMessage(MessageConstants.DELETE_SUCCESS))))
                .onErrorResume(e -> Mono.just(Result.<Object>fail().message(e.getMessage())));
    }

    /**
     * 根据配置分类和键删除配置
     */
    @DeleteMapping("/{sort}/{key}")
    @PreAuthorize("hasAuthority('sysconfig:delete')")
    @LogCollector
    public Mono<Result<Object>> deleteBySortAndKey(@PathVariable String sort, @PathVariable String key) {
        return sysConfigService.deleteBySortAndKey(sort, key)
                .then(Mono.just(Result.ok().message(I18n.getMessage(MessageConstants.DELETE_SUCCESS))))
                .onErrorResume(e -> Mono.just(Result.<Object>fail().message(e.getMessage())));
    }

    /**
     * 批量删除配置
     */
    @DeleteMapping("/batch")
    @PreAuthorize("hasAuthority('sysconfig:delete')")
    @LogCollector
    public Mono<Result<Object>> batchDelete(@RequestBody List<String> keys) {
        return sysConfigService.deleteByKeys(keys)
                .then(Mono.just(Result.ok().message(I18n.getMessage(MessageConstants.DELETE_SUCCESS))))
                .onErrorResume(e -> Mono.just(Result.<Object>fail().message(e.getMessage())));
    }

    /**
     * 根据配置键获取配置值
     */
    @GetMapping("/value/{key}")
    @PreAuthorize("hasAuthority('sysconfig:get')")
    public Mono<Result<String>> getConfigValue(@PathVariable String key) {
        return sysConfigService.getConfigValue(key)
                .map(Result::ok)
                .switchIfEmpty(Mono.just(Result.<String>fail().message(I18n.getMessage(MessageConstants.DATA_NOT_FOUND))))
                .onErrorResume(e -> Mono.just(Result.<String>fail().message(e.getMessage())));
    }

    /**
     * 根据配置分类和键获取配置值
     */
    @GetMapping("/value/{sort}/{key}")
    //@PreAuthorize("hasAuthority('sysconfig:get')")
    public Mono<Result<String>> getConfigValueBySortAndKey(@PathVariable String sort, @PathVariable String key) {
        return sysConfigService.getConfigValue(sort, key)
                .map(Result::ok)
                .switchIfEmpty(Mono.just(Result.<String>fail().message(I18n.getMessage(MessageConstants.DATA_NOT_FOUND))))
                .onErrorResume(e -> Mono.just(Result.<String>fail().message(e.getMessage())));
    }

    /**
     * 根据配置分类查询配置列表
     */
    @GetMapping("/sort/{sort}")
    @PreAuthorize("hasAuthority('sysconfig:list')")
    public Mono<Result<List<SysConfigPo>>> listBySort(@PathVariable String sort) {
        return sysConfigService.findBySort(sort)
                .collectList()
                .map(Result::ok)
                .onErrorResume(e -> Mono.just(Result.<List<SysConfigPo>>fail().message(e.getMessage())));
    }
} 